// Copyright 2007-2010 Comdiv (F. Sadykov) - http://code.google.com/u/fagim.sadykov/
// Supported by Media Technology LTD 
//  
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//  
//      http://www.apache.org/licenses/LICENSE-2.0
//  
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// 
// MODIFICATIONS HAVE BEEN MADE TO THIS FILE
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Web;
using Comdiv;


#if !MONORAIL
using System.Web.Mvc;
using Comdiv;
using Comdiv.Extensions;

#endif
#if MONORAIL
namespace Castle.MonoRail.Views.Brail
#else

namespace MvcContrib.Comdiv.ViewEngines.Brail
#endif
{
    /// <summary>
    ///Base class for all the view scripts, this is the class that is responsible for
    /// support all the behind the scenes magic such as variable to PropertyBag trasnlation, 
    /// resources usage, etc. 
    /// </summary>
    public abstract partial class BrailBase{
        private string __getCacheKeyResult = null;
#if !MONORAIL
        protected ViewContext __viewContext;
#endif
        public string FileName { get; set; }
        protected TextWriter CacheIndependedWriter { get; set; }


        public virtual string inspect(){

//debug propose;
            int i = 1;
            return i.ToString();
        }

#if !MONORAIL
        /// <summary>
        /// Initialize all the properties that a script may need
        /// One thing to note here is that resources are wrapped in ResourceToDuck wrapper
        /// to enable easy use by the script
        /// </summary>
        /// 
        public HtmlHelper Html{
            get { return (HtmlHelper) Properties["html"]; }
        }

        public UrlHelper Url{
            get { return (UrlHelper) Properties["url"]; }
        }
#endif

        public void SetProperty(string name, object value){
            Properties[name] = value;
        }

        public object TryGetParameterNoIgnoreNull(string name){
            if (!Properties.Contains(name)){
                return null;
            }
            return Properties[name];
        }

        protected object best(params object[] parameters){
            object current = null;
            foreach (object parameter in parameters){
                current = parameter;
                if (null != current){
                    break;
                }
            }
            return current;
        }

        protected readonly IDictionary<string,object> exportProperties = new Dictionary<string,object>();

        public void __Export(string name){
            __Export(name, Missing.Value);

            
        }

        public void __Export(string name,object obj){
            if(!exportProperties.ContainsKey(name)){
                exportProperties.Add(name,obj);
            }
        }

        public void BindExportedProperties(){
            BindExportedProperties(parent);
        }

        public void BindExportedProperties(BrailBase target){
            foreach (var propname in exportProperties){
                if (!(propname.Value is Missing))
                {
                    target.Properties[propname.Key] = propname.Value;
                }
                else{
                    target.Properties[propname.Key] = TryGetParameterNoIgnoreNull(propname.Key);
                }
            }
        }

        protected T _convert<T>(object obj){
            return obj.to<T>();
        }

        protected bool isempty(object e){
            if (null == e){
                return true;
            }
            return (e as IEnumerable).Cast<object>().Count() == 0;
        }

        private TextWriter _catchwriter = null;

        public void _catchoutput(){
            _catchwriter = new StringWriter();
        }

        public string _endcatchoutput(){
            string result = _catchwriter.ToString();
            _catchwriter = null;
            return result;
        }

        protected IEnumerable<int> range(int start,int finish){
            return range(start, finish, x=>{
                                            if(start<=finish){
                                                return x + 1;
                                            }else{
                                                return x - 1;
                                            }
                                        });
        }

        protected IEnumerable<T> range<T>(T start,T finish, Func<T,T> next){
            var current = start;
            do{
                yield return current;
                current = next(current);
            } while (!current.Equals(finish));
            
        }

        

        protected IList<object> _wrapcollection(object col){
            if (null == col){
                return null;
            }
            if (col is IEnumerable){
                return ((IEnumerable) col).Cast<object>().ToList();
            }
            return new[]{col}.ToList();
        }

        protected string _escape(object html){
            return HttpUtility.HtmlEncode((html ?? "").ToString()).Replace("'", "&apos;");
        }

        protected internal bool __isCacheable(){
            return _key() != null;
        }

        protected internal string __getCacheKey(){
            if (null == __getCacheKeyResult){
                Type t = GetType();
                __getCacheKeyResult = GetType().FullName + "_" + t.Assembly.GetHashCode() + "_" + t.GetHashCode() + "_"
                                      + _key();
            }
            return __getCacheKeyResult;
        }

        protected internal virtual string _key(){
            return null;
        }

        protected internal void writeToCache(){
            if (__isCacheable()){
                string content1 = outputStream.ToString();
                viewEngine.OutputCache[__getCacheKey()] = content1;
                string content = content1;
                outputStream = CacheIndependedWriter;
                outputStream.Write(content);
            }
        }

        protected internal bool readCache(){
            bool fromcache = false;
            if (__isCacheable()){
                if (viewEngine.OutputCache.ContainsKey(__getCacheKey())){
                    outputStream.Write(viewEngine.OutputCache[__getCacheKey()]);
                    fromcache = true;
                }
                else{
                    outputStream = new StringWriter();
                }
            }
            return fromcache;
        }
    }
}